using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.Extensions.Configuration;
using MongoDB.Bson;
using MongoDB.Driver;

namespace microsoft_TODO.MongoCore.Repositories
{
  public class BaseRepository<T>
  {
    protected IMongoCollection<T> Collection;
    protected IMongoCollection<BsonDocument> BsonCollection;
    public BaseRepository(IConfiguration configuration, string collectionName)
    {
      var connStr = configuration.GetConnectionString("Mongo"); // 连接需要认证，通过一条语句并指定了数据表
      var client = new MongoClient(connStr);
      var db = client.GetDatabase("todo");
      Collection = db.GetCollection<T>(collectionName);
      BsonCollection = db.GetCollection<BsonDocument>(collectionName);
    }

    public T Insert(T entity)
    {
      this.Collection.InsertOne(entity);
      return entity;
    }

    public T FirstOrDefault(Expression<Func<T, bool>> exp)
    {
      return this.Collection.Find(exp).FirstOrDefault();
    }

    public List<T> GetAllList(Expression<Func<T, bool>> exp = null)
    {
      return exp == null
        ? this.Collection.AsQueryable().ToList()
        : this.Collection.Find(exp).ToList();
    }

    public IQueryable<T> GetAll()
    {
      return this.Collection.AsQueryable();
    }

    public void Update(Expression<Func<T, bool>> exp, UpdateDefinition<T> update){
      this.Collection.UpdateMany(exp, update);
    }

    public bool Delete(Expression<Func<T, bool>> exp)
    {
      return this.Collection.DeleteMany(exp).DeletedCount > 0;
    }

    public long Count(Expression<Func<T, bool>> exp)
    {
      return this.Collection.Count(exp);
    }

    public bool IsExistent(Expression<Func<T, bool>> exp)
    {
      return this.Collection.Find(exp).Any();
    }
  }
}